﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Windows.Data;
using System.Xml.Linq;
using System.Windows.Threading;
using System.Net;
using System.IO;

namespace RssReader
{

    public static class XElementExtension
    {
        public static string GetString ( this XElement e , string name ) 
        { 
             if ( e.Element( name ) != null) 
             {
                return e.Element( name).Value ; 
             } 
            return string.Empty ; 

        } 
    } 
    public class Entity : INotifyPropertyChanged
    {

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        protected void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler h = this.PropertyChanged;
            if (h != null)
                h(this, new PropertyChangedEventArgs(name));
        }        
    }

    public class Post : Entity 
    {
        public string Title { get; set; }
        public DateTime DatePublished { get; set; }
        public string URL { get; set;  }
        public string Author { get; set; }
        public string Description { get; set; } 

    } 

    

    public class Feed : Entity  
    {
       
        public Feed(string url)
        {
            Uri = new Uri(url);

            if (AutoDownload)
            {
                BackgroundWorker bg = new BackgroundWorker();
                bg.DoWork += new DoWorkEventHandler(bg_DoWork);
                bg.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);
                bg.RunWorkerAsync(); 
            } 
        }

        bool _autoDownload = true; 
        public bool AutoDownload
        {
            get
            {
                return _autoDownload; 
            }
            set
            {
                _autoDownload = value; 
            }
        } 

        void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
             
        }

        void bg_DoWork(object sender, DoWorkEventArgs e)
        { 
             
            XDocument doc = XDocument.Load(this.Uri.ToString());
             
            try
            {
                XElement feed = doc.Element("rss").Element("channel");

                this.Title =  feed.Element("title").Value;
                this.ImagePath = feed.GetString( "image" );
                if (this.ImagePath == null) this.ImagePath = string.Empty;
                this.Description = Helpers.ToUTF16(feed.Element("description").Value); 
                
                this.Link = feed.Element("link").Value; 



                var query = (from item in doc.Descendants("item")
                             let
                             datPublished = Helpers.ParseDate(item.Element("pubDate").Value)
                             orderby datPublished descending
                             where datPublished > DateTime.Now.AddDays(-300)
                             select new Post
                               {
                                   DatePublished = Helpers.ParseDate(item.Element("pubDate").Value),
                                   Title = item.Element("title").Value,
                                   Description = Helpers.ToUTF16 (item.Element("description").Value), 
                                   Author = item.GetString("Author"), 
                                   // Category = item.Element("category").Value , 
                                   URL = item.Element("link").Value

                               });

                App.Current.Dispatcher.BeginInvoke( ((Action) delegate()
                {
                    foreach (Post p in query)
                    {
                        if (string.IsNullOrEmpty(p.Author))
                            p.Author = this.Title; 
                        this.Posts.Add(p);
                    }

                }), null); 



                
            }
            catch (Exception ex)
            {
                this.IsValid = false; 
            } 
        }

        public string _imagePath; 
        public string ImagePath {
            get
            {
                return _imagePath;
            } 
            set 
            {
                if (_imagePath != value)
                {
                    _imagePath = value;
                    OnPropertyChanged("ImagePath"); 
                } 
            } 
             
        }


        public string _Link;
        public string Link
        {
            get
            {
                return _Link;
            }
            set
            {
                if (_Link != value)
                {
                    _Link = value;
                    OnPropertyChanged("Link");
                }
            }

        }


        public string _Description;
        public string Description
        {
            get
            {
                return _Description;
            }
            set
            {
                if (_Description != value)
                {
                    _Description = value;
                    OnPropertyChanged("Description");
                }
            }

        } 
        public Uri  Uri { get; internal set; }
        public bool IsValid { get; internal set; }
       
        


        protected string _title; 
        public string Title {
            get
            {
                return _title;
            }
            private set
            {
                if (_title != value)
                {
                    _title = value ;
                    OnPropertyChanged("Title");
                }
            } 
        }

        protected ObservableCollection<Post> _posts = new ObservableCollection<Post>(); 
        public ObservableCollection<Post> Posts
        {
            get
            {
                return _posts; 
            }            
        } 
    } 

    public class ViewModel : Entity 
    {
        #region INotifyPropertyChanged Members

        private ObservableCollection<Feed> _feeds = new ObservableCollection<Feed>(); 
        public ObservableCollection<Feed> Feeds
        {
            get
            {
                return _feeds; 
            }          
        }


        Feed _selectedFeed;
        public Feed SelectedFeed
        {
            get
            {
                return _selectedFeed;
            }
            set
            {
                _selectedFeed = value;
                OnPropertyChanged("SelectedFeed");
            }
        }

        Post _selectedPost; 
        public Post SelectedPost
        {
            get
            {
                return _selectedPost; 
            }
            set
            {
                _selectedPost = value;
                OnPropertyChanged("SelectedPost"); 
            }
        } 
        event PropertyChangedEventHandler PropertyChanged
        {
            add { throw new NotImplementedException(); }
            remove { throw new NotImplementedException(); }
        }

        #endregion
    }
}
